package com.benjaminwan.read.free.utils

import java.util.*

/**
 * 校验是否为Hex格式
 * 例：0f -> true
 * 例：f -> false //字符数量为奇数
 * 例：00 -> true
 * 例：f0 -> true
 * 例：31 32 33 -> true //可以间隔空格
 * 例：313233  -> true //也可以不间隔空格
 * 例：3132 33  -> true //也可以不间隔空格
 * 例：31 3G 33 -> false //不可以含有G(只能含有0~9和A~F)
 * @return true=是Hex字符串
 */
fun String.isHexStrValid(): Boolean {
    val data = this.replace(" ", "").toUpperCase(Locale.getDefault())
    val regex = "^[0-9A-F]+$".toRegex()
    val isHex = data.matches(regex)//是否仅含有Hex字符
    val isEven = (data.length % 2) == 0 //是否为偶数
    return isHex && isEven
}

/**
 * 把ByteArray转为Hex字符串
 * 例：0x 31 32 33 -> "31 32 33"
 * 例：0x 00 ff f0 0f -> "00 FF F0 0F"
 * @return 返回转换后的字符串
 */
@kotlin.ExperimentalUnsignedTypes
fun ByteArray.toHex(separator: CharSequence = " "): String {
    if (this.isEmpty()) return ""
    val result: StringBuilder = StringBuilder()
    this.forEachIndexed { index, byte ->
        val item = byte.toUByte().toString(16)
        if (item.length < 2) {//长度为1时补0
            result.append("0")
        }
        if (index == this.lastIndex) {
            result.append(item)
        } else {
            result.append(item).append(separator)
        }
    }
    return result.toString()
}

fun List<Byte>.toHex(): String =
    this.toByteArray().toHex()

/**
 * Byte转Hex字符串
 * 例：0x 0f -> "0F"
 * 例：0x ff -> "FF"
 * @return 返回转换后的字符串
 */
@kotlin.ExperimentalUnsignedTypes
fun Byte.toHex(): String {
    val result: StringBuilder = StringBuilder()
    val hex = this.toUByte().toString(16).toUpperCase(Locale.getDefault())
    if (hex.length < 2) {
        result.append("0")
    }
    result.append(hex)
    return result.toString()
}

/**
 * 把Hex字符串转为ByteArray
 * 例："31 32 33" -> 0x 31 32 33
 * 例："00 FF F0 0F" -> 0x 00 ff f0 0f
 * @return 返回ByteArray
 */
@kotlin.ExperimentalUnsignedTypes
fun String.hexToByteArray(): ByteArray {
    if (this.isEmpty()) return ByteArray(0)
    val data = this.replace(" ", "").toUpperCase(Locale.getDefault())
    val length = data.length - 1
    val byteList: MutableList<UByte> = mutableListOf()
    for (i in 0..length step 2) {
        val subStr = data.substring(i, i + 2)
        byteList.add(subStr.toUByte(16))
    }
    return byteList.toUByteArray().toByteArray()
}